//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using OpenLS.Spreadsheet.Expressions;
using OpenLS.Spreadsheet.Parsing;

namespace OpenLS.Spreadsheet.Chart
{
    struct InvalidRange
    {
        private readonly EvaluationContext _context;
        public InvalidRange(Workbook workbook, string formula)
        {
            Contract.Requires(workbook != null);
            _context = new WorkbookEvaluationContext(workbook);
            _invalidFormula = null;
            var expressionParser = new ExpressionParser(workbook, LocalizationMode.NonLocalized, CellReferenceMode.Dynamic);
            var f = formula;
            if (!(f.Trim().StartsWith("=")))
                f = "=" + formula;
            _expression = expressionParser.Expression(f);
            if (Expression == null)
                _invalidFormula = formula;
        }
        public InvalidRange(Worksheet worksheet, string formula)
        {
            Contract.Requires(worksheet != null);
            _context = new WorksheetEvaluationContext(worksheet);
            _invalidFormula = null;
            var expressionParser = new ExpressionParser(worksheet, null, LocalizationMode.NonLocalized, CellReferenceMode.Dynamic);
            var f = formula;
            if (!(f.Trim().StartsWith("=")))
                f = "=" + formula;
            _expression = expressionParser.Expression(f);
            if (Expression == null)
                _invalidFormula = formula;
        }
        public InvalidRange(EvaluationContext context, Expression expression)
        {
            this._context = context;
            _expression = expression;
            _invalidFormula = null;
        }
        public Range Range
        {
            get
            {
                if (_expression is RangeReferenceExpression)
                    return ((RangeReferenceExpression)_expression).RangeReference.Range;
                if (_expression is CellReferenceExpression)
                {
                    var expression = (CellReferenceExpression) _expression;
                    return expression.Cell(_context).ToRange();
                }
                Debug.WriteLine("Invalid range " + _expression);
                return null;
            }
        }
        private readonly Expression _expression;
        internal Expression Expression { get { return _expression; } }
        private readonly string _invalidFormula;

        public string InvalidFormula
        {
            get { return _invalidFormula; }
        }



        internal string Formula
        {
            get{
                if (Expression != null)
                    return Expression.GetText(new TextContext(new InvalidEvaluationContext())); 
                return _invalidFormula;
            }
        }
    }
}
